/**
 * ISSG Sony China 2010 
 *
 */
package cn.com.dragonsoftbravo.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * Class DateUtils used for Date-related operation
 * 
 * @copyright Promoters Sell-thru System, ISSG, Sony China
 * @author Dennis
 * @date 2010-8-27
 */
public class DateUtils {

	private final String MAX_DATE = "9999-12-31";

	private SimpleDateFormat simpleDateFormat;

	private static final String WEEK_CN = "日一二三四五六";

	public DateUtils(String pattern) {
		this.simpleDateFormat = new SimpleDateFormat(pattern, Locale.getDefault());
	}

	public DateUtils() {
		this.simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
	}

	/**
	 * Formats a Date into a date/time string
	 * 
	 * @param date
	 * @return the formatted time string.
	 */
	public final String format(Date date) {
		if (date == null) {
			return null;
		} else {
			String d = simpleDateFormat.format(date);
			if (MAX_DATE.equalsIgnoreCase(d)) {
				return null;
			} else {
				return d;
			}
		}
	}

	public static String today() {
		SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
		String d = s.format(new Date());
		return d;
	}

	public static Date parse(String date, String patten) {
		SimpleDateFormat sdf = new SimpleDateFormat(patten);
		try {
			return sdf.parse(date);
		} catch (ParseException e) {
			return null;
		}
	}

	public static String currMonth() {
		return formatMonth(new Date());
	}

	public static String formatDay(Date date) {
		SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
		String d = s.format(date);
		return d;
	}
	
	public static Date formatDayD2D(Date date) {
		SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
		String d = s.format(date);
		Date n = null;
		try {
			n = s.parse(d);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return n;
	}

	public static String formatDate(Date date) {
		SimpleDateFormat s = new SimpleDateFormat("dd/MM/yyyy");
		String d = s.format(date);
		return d;
	}

	public static String formatCompleteDate(Date date) {
		SimpleDateFormat s = new SimpleDateFormat("MM-dd HH:mm:ss");
		String d = s.format(date);
		return d;
	}
	
	
	public static String formatDate(Date date, String format) {
		SimpleDateFormat s = new SimpleDateFormat(format);
		String d = s.format(date);
		return d;
	}

	public static String formatMonth(Date date) {
		SimpleDateFormat s = new SimpleDateFormat("yyyy-MM");
		String d = s.format(date);
		return d;
	}

	/**
	 * return CN week, temporal code, need better way to get it
	 * 
	 * @param date
	 * @return
	 */
	public static String dayOfWeek(Date date) {
		if (date == null) {
			return null;
		} else {
			Calendar cal = Calendar.getInstance(Locale.getDefault());
			cal.setTime(date);
			return "星期" + WEEK_CN.charAt(cal.get(Calendar.DAY_OF_WEEK) - 1);
		}
	}

	public static List<String> getWeekdays() {

		List<String> weekDays = new ArrayList<String>();

		Calendar calendar = Calendar.getInstance();
		while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
			calendar.add(Calendar.DATE, -1);
		}

		for (int i = 0; i < 7; i++) {
			weekDays.add(formatDay(calendar.getTime()));
			calendar.add(Calendar.DATE, 1);
		}

		return weekDays;
	}

	/**
	 * get the days num of month
	 * 
	 * @param date
	 * @return
	 */
	public static int getMonthDayNum(Date date) {

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		;
		Integer[] monthDay = new Integer[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		int year = calendar.get(Calendar.YEAR);
		if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
			monthDay[1] = 29;
		}
		return monthDay[calendar.get(Calendar.MONTH)];
	}

	public static List<Date> getCurrentMonthRange() {
		Calendar c1 = Calendar.getInstance();
		c1.set(Calendar.DAY_OF_MONTH, 1);
		Date start = c1.getTime();

		Calendar c2 = Calendar.getInstance();
		c2.set(Calendar.DAY_OF_MONTH, c2.getActualMaximum(Calendar.DATE));
		Date end = c2.getTime();

		return Arrays.asList(start, end);
	}

	public static int getWeekdayCountByMonth(int year, int month) {

		month--;

		Calendar c = Calendar.getInstance();

		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, month);
		c.set(Calendar.DAY_OF_MONTH, 1);

		int count = 1;

		while (c.get(Calendar.MONTH) == month) {
			int weekDay = c.get(Calendar.DAY_OF_WEEK);
			if (weekDay != Calendar.SUNDAY && weekDay != Calendar.SATURDAY) {
				count++;
			}
			c.add(Calendar.DAY_OF_MONTH, 1);
		}
		return count;
	}

	public static List<Date> getWeekdaysByMonth(int year, int month) {

		month--;

		Calendar c = Calendar.getInstance();

		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, month);
		c.set(Calendar.DAY_OF_MONTH, 1);

		List<Date> dates = new ArrayList<Date>();

		while (c.get(Calendar.MONTH) == month) {
			int weekDay = c.get(Calendar.DAY_OF_WEEK);
			if (weekDay != Calendar.SUNDAY && weekDay != Calendar.SATURDAY) {
				dates.add(c.getTime());
			}
			c.add(Calendar.DAY_OF_MONTH, 1);
		}
		return dates;
	}

	public static Date getFirstDayOfMonth(int year, int month) {

		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.add(Calendar.DAY_OF_MONTH, -1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		Date firstDate = cal.getTime();
		return firstDate;
	}

	public static Date getLastDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.add(Calendar.DAY_OF_MONTH, -1);
		Date lastDate = cal.getTime();

		return lastDate;
	}

	public static Date getStartOfToday() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		return c.getTime();

	}

	public static Date getEndOfToday() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		return c.getTime();
	}

	public static Date getStartOfDay(Date date) {
		
		Calendar c = Calendar.getInstance();
		
		if(date == null){
			c.set(Calendar.YEAR, 1970);
			return c.getTime();
		}
		
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		return c.getTime();
	}

	public static Date getEndOfDay(Date date) {
		
		Calendar c = Calendar.getInstance();
		
		if(date == null){
			c.set(Calendar.YEAR, 2100);
			return c.getTime();
		}
		
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		return c.getTime();
	}
	
}
